import common from '@ohos.app.ability.common';
import window from '@ohos.window';
import bundleManager from '@ohos.bundle.bundleManager';
import resourceManager from '@ohos.resourceManager';
import HashMap from '@ohos.util.HashMap';
import { JsQtModule } from './JsQtModule';
import deviceInfo from '@ohos.deviceInfo';
import inputDevice from '@ohos.multimodalInput.inputDevice';
import QtJsObjectLoader from './JsObjectLoader';
import { UIContext } from '@kit.ArkUI';
import JsLogger from './JsLogger';
import { AbilityInfo } from './JsAbilityInfo'

interface ApplicationDirs {
  tempDir: string,
  filesDir: string,
  cacheDir: string,
  databaseDir: string,
  bundleCodeDir: string,
  preferencesDir: string,
  distributedFilesDir: string,
  qmlDir: string
}

class JsDataStore {
  private abilities: AbilityInfo[] = []
  private currentContext: common.UIAbilityContext = null;
  private elementName: bundleManager.ElementName = null;
  private jsModules: JsQtModule[] = [];
  private applicationDirs: ApplicationDirs;
  private qtMajorVersion: number = 0;
  private qtNativeModules: HashMap<string, any> = new HashMap();
  private jsObjectLoader: QtJsObjectLoader = new QtJsObjectLoader;

  constructor() {
  }

  setApplicationDirs(context: common.UIAbilityContext) {
    this.currentContext = context
    let appContext = context.getApplicationContext();
    let dirs: ApplicationDirs = {
      tempDir: appContext.tempDir,
      filesDir: appContext.filesDir,
      cacheDir: appContext.cacheDir,
      databaseDir: appContext.databaseDir,
      bundleCodeDir: appContext.bundleCodeDir,
      preferencesDir: appContext.preferencesDir,
      distributedFilesDir: appContext.distributedFilesDir,
      qmlDir: context.resourceDir + "/qml"
    };
    this.applicationDirs = dirs;
  }

  addAbility(info: AbilityInfo) {
    this.abilities.push(info);
    if(this.abilities.length > 0){
      this.currentContext = this.abilities[this.abilities.length-1].context;
    }
  }

  removeAbility(id: number) {
    let context: undefined | common.UIAbilityContext = undefined;
    for (let i = 0; i < this.abilities.length; ++i) {
      if (this.abilities[i].id === id) {
        context = this.abilities[i].context
        this.abilities.splice(i, 1)
        break;
      }
    }

    if (this.abilities.length === 0) {
      this.currentContext = undefined
      return;
    }

    if (context !== undefined && this.currentContext == context) {
      this.currentContext = this.abilities[0].context;
      this.getQtNativeModule("QPA").setResourceManager(this.currentContext.resourceManager);
    }
  }

  getAbilityInstanceKey():string|undefined{
    if(this.abilities.length > 0){
      return this.abilities[this.abilities.length-1]?.instanceKey;
    }
    return undefined
  }

  getContext(id: number): common.UIAbilityContext {
    for (let i = 0; i < this.abilities.length; ++i) {
      if (this.abilities[i].id === id) {
        return this.abilities[i].context
      }
    }
  }

  getValidContext() : common.UIAbilityContext{
    return this.currentContext;
  }

  getWindowStage(name: string): window.WindowStage {
    for (let i = 0; i < this.abilities.length; ++i) {
      if (this.abilities[i].name === name) {
        return this.abilities[i].windowStage;
      }
    }
    return undefined
  }

  getApplicationDirs(): ApplicationDirs {
    return this.applicationDirs;
  }

  setElementName(en: bundleManager.ElementName) {
    this.elementName = en;
  }

  getElementName(): bundleManager.ElementName {
    return this.elementName;
  }

  getResourceManager(): resourceManager.ResourceManager {
    return this.getValidContext().resourceManager;
  }

  addJsModule(module: JsQtModule) {
    this.jsModules.push(module);
  }

  getJsModules(): JsQtModule[] {
    return this.jsModules;
  }

  getJsObjectLoader(): QtJsObjectLoader {
    return this.jsObjectLoader;
  }

  getQtMajorVersion(): number {
    return this.qtMajorVersion;
  }

  setQtMajorVersion(version: number) {
    this.qtMajorVersion = version;
  }

  addQtNativeModule(name: string, module: any) {
    this.qtNativeModules.set(name, module);
  }

  getQtNativeModule(name: string): any {
    return this.qtNativeModules.get(name);
  }

  deviceType(): string {
    // 现目前在pc、pad上模拟成手机端
    // return 'default';
    return deviceInfo.deviceType;
  }

  displayVersion(): string {
    return deviceInfo.displayVersion;
  }

  defaultShowIsMaximized(): boolean {
    return false;
    // return deviceInfo.deviceType == "default" || deviceInfo.deviceType == "tablet";
  }

  async isTouchPad(): Promise<boolean> {
    try {
      let devices = await inputDevice.getDeviceList();
      for (let i = 0; i < devices.length; ++i) {
        let deviceInfo = inputDevice.getDeviceInfoSync(devices[i]);
        if (deviceInfo.sources.includes('touchpad')) {
          return true;
        }
      }
      return false;
    } catch (err) {
      JsLogger.error('Failed to call getDeviceInfoSync. Cause: %{public}s', JSON.stringify(err));
      return false;
    }
  }
}

export default new JsDataStore;